/**************************************************************
 * Author: DO HOANG HAI
 * Date of Creation:
 * Last modification:
 * 
 * Description:This class provides functions to interact with
 * data in file FileInfo.XML. An object of this class represents
 * for an FileInfo object and corresponds to a fileInfo element in
 * the XML file.
 **************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using Pbdms.Common;
using Pbdms.Common.DataObject;

namespace Pbdms.DataAccess.DataProvider
{
    interface IFileInfoProviderInterface : IProviderInterface
    {       
        FileInfo selectFromDB();
    }
    /// <summary>
    /// This class provides functions to interact with
    /// data in file FileInfo.XML. An object of this class represents
    /// for an FileInfo object and corresponds to a fileInfo element in
    /// the XML file
    /// </summary>
    public class FileInfoProvider : IFileInfoProviderInterface
    {
        private FileInfo fileInfoObj;
        private const String FILENAME = "fileInfo.xml";

        /// <summary>
        /// create new FileInfo Object with a new Provider refers to
        /// </summary>
        /// <param name="id">id of the FileInfo object</param>
        /// <param name="existence">True if the file is existing, False othewise</param>
        public FileInfoProvider(String id)
        {
            this.fileInfoObj = new FileInfo(id);
        }

        /// <summary>
        /// create a FileInfoProvider object for an existing FileInfo Object
        /// </summary>
        /// <param name="fileInfoObj"></param>
        public FileInfoProvider(FileInfo fileInfoObj)
        {
            this.fileInfoObj = fileInfoObj;
        }

        /// <summary>
        /// create new FileInfo Object with a new Provider refers to
        /// </summary>
        /// <param name="id"></param>
        /// <param name="existence"></param>
        /// <returns></returns>
        public static FileInfoProvider create(String id)
        {
            return new FileInfoProvider(id);
        }

        /// <summary>
        /// create a FileInfoProvider object for an existing FileInfo Object
        /// </summary>
        /// <param name="fileInfoObj"></param>
        /// <returns></returns>
        public static FileInfoProvider create(FileInfo fileInfoObj)
        {
            return new FileInfoProvider(fileInfoObj );  
        }

        /// <summary>
        /// get the XPath of the entry in the XML file, including the attribute id
        /// </summary>
        /// <returns></returns>
        private String getXPath()
        {
            return "/root/fileInfo[@id='" + fileInfoObj.ID + "']";            
        }

        /// <summary>
        /// create a new FileInfo object from current Provider with fresh data
        /// taken from XML file
        /// </summary>
        /// <returns></returns>
        public FileInfo getFileInfoObj()
        {
            return fileInfoObj;
        }
       
        /// <summary>
        /// update a specific value of an element in XML file
        /// </summary>
        /// <param name="name">name of the element</param>
        /// <param name="value"></param>
        public void updateElementToDB(String name, Object value)
        {
            XmlHelper.create(FILENAME).updateTypedElement(getXPath() + "/" + name, value);
        }

        /// <summary>
        /// update database with new values of attributes
        /// </summary>
        public void updateAllToDB()
        {
            XmlHelper.create(FILENAME).updateUnTypedElement(getXPath() + "/fileName", fileInfoObj.FileName);
            XmlHelper.create(FILENAME).updateUnTypedElement(getXPath() + "/location", fileInfoObj.Location );
            XmlHelper.create(FILENAME).updateTypedElement(getXPath() + "/size", fileInfoObj.Size);
            if (fileInfoObj.Existence)
                XmlHelper.create(FILENAME).updateTypedElement(getXPath() + "/existence", 1 );
            else
                XmlHelper.create(FILENAME).updateTypedElement(getXPath() + "/existence", 0 );

        }

        /// <summary>
        /// update fileInfo object with fresh data take from database
        /// </summary>
        public void updateFromDB()
        {
            fileInfoObj = selectFromDB();
        }

        /// <summary>
        /// create a new FileInfo Oject from database correspondint to this provider
        /// </summary>
        /// <param name="id">id of the object in XML file</param>
        /// <returns></returns>
        public FileInfo selectFromDB()
        {
            //select all value of the this comment in database
            FileInfo fileInfoObject = new FileInfo(fileInfoObj.ID);
            fileInfoObject.FileName = XmlHelper.create(FILENAME).getInnerXML(getXPath() + "/fileName");
            fileInfoObject.Location = XmlHelper.create(FILENAME).getInnerXML(getXPath() + "/location");
            String sSize = XmlHelper.create(FILENAME).getInnerXML(getXPath() + "/size");
            if (sSize.Equals(""))
            {
                fileInfoObject.Size = 0;
            }
            else
                fileInfoObject.Size = long.Parse(sSize);
           
            if (XmlHelper.create(FILENAME).getInnerXML(getXPath() + "/existence").Equals("1"))
                fileInfoObject.Existence = true;
            else
                fileInfoObject.Existence = false;

            return fileInfoObject;          
        }
        
        /// <summary>
        /// delete from the database
        /// </summary>
        public void deleteDB()
        {
            XmlHelper.create(FILENAME).deleteSelf(getXPath());
        }

        public static void appendFileInfo(FileInfo fileInfoObj)
        {
            //construct xml text
            StringBuilder sb = new StringBuilder();
            sb.Append("<fileInfo id='" +fileInfoObj.ID +"'>");
            sb.Append("<location>" + fileInfoObj.Location +"</location>");
            sb.Append("<size>" + fileInfoObj.Size+"</size>");
            sb.Append("<fileName>" + fileInfoObj.FileName + "</fileName>");
            if (fileInfoObj.Existence)
                sb.Append("<existence>1</existence>");            
            else
                sb.Append("<existence>0</existence>");
            sb.Append("</fileInfo>");
            
            //append new child
            XmlHelper.create("fileInfo.xml").appendChild("/root", sb.ToString());
        }
    }
}
